<template>
  <div class="split" ref="parent">
    <slot></slot>
  </div>
</template>

<script lang="ts">
import Split from "split.js";
import {defineComponent, onMounted, ref, SetupContext, VNode, watch,} from "vue";

interface IDataContainer {
  instance: any;
  elements: Array<any> | undefined;
  sizes: Array<number> | undefined;
  minSizes: Array<number> | undefined;
  destroy: Function,
}

export default defineComponent({
  emits: ["onDrag", "onDragStart", "onDragEnd"],
  props: {
    direction: {type: String, default: "horizontal"},
    gutterSize: {type: Number, default: 8},
    firstAreaDefaultSize: Number,
    lastAreaDefaultSize: Number,
  },

  setup(props, ctx: SetupContext) {
    const parent = ref(null);
    const dataVal = {
      elements: new Array<any>(),
      sizes: new Array<number>(),
      minSizes: new Array<number>(),
      instance: null,
      //@ts-ignore
      destory: Function
    };

    //@ts-ignore
    const data = ref(dataVal as IDataContainer);
    watch(() => props.direction, (value, oldValue) => {
      init()
    })
    let useFirstDefaultSize = props.firstAreaDefaultSize && props.firstAreaDefaultSize > 0;
    let useLastDefaultSize = props.lastAreaDefaultSize && props.lastAreaDefaultSize > 0;
    let splitSumCount = 0;
    const init = () => {
      if (data.value.instance !== null) {
        data.value.instance?.destroy();
      }
      let splitCount = 0;
      data.value.instance = null;
      const splitOptions = {
        direction: props.direction || "horizontal",
        sizes: data.value.sizes || 50,
        minSize: data.value.minSizes || 100,
        gutterSize: props.gutterSize || 8,
        cursor: props.direction === "horizontal" ? "col-resize" : "row-resize",
        onDrag: function () {
          useFirstDefaultSize = false;
          useLastDefaultSize = false;
          ctx.emit("onDrag", data.value.instance?.getSizes());
        },
        onDragStart: function () {
          ctx.emit("onDragStart", data.value.instance?.getSizes());
        },
        onDragEnd: function () {
          ctx.emit("onDragEnd", data.value.instance?.getSizes());
        },
      };
      if (useFirstDefaultSize) {
        splitOptions["elementStyle"] = function elementStyle(dimension, size, gutterSize) {
          // console.log("@@@@", dimension, size, gutterSize)
          splitCount++
          let res
          if (splitSumCount === 2 && useFirstDefaultSize && !useLastDefaultSize) {
            // 2个split-area & 使用firstAreaDefaultSize & 未使用lastAreaDefaultSize
            if (splitCount === 1) {
              res = {[dimension]: `calc(${props.firstAreaDefaultSize}px - ${gutterSize}px)`};
            } else {
              res = {[dimension]: `calc(100% - ${props.firstAreaDefaultSize + gutterSize}px)`};
            }
          } else if (splitSumCount === 2 && !useFirstDefaultSize && useLastDefaultSize) {
            // 2个split-area & 未使用firstAreaDefaultSize & 使用了lastAreaDefaultSize
            if (splitCount === 2) {
              res = {[dimension]: `calc(${props.lastAreaDefaultSize}px - ${gutterSize}px)`};
            } else {
              res = {[dimension]: `calc(100% - ${props.lastAreaDefaultSize + gutterSize}px)`};
            }
          } else if (splitSumCount === 3 && useFirstDefaultSize && useLastDefaultSize) {
            // 3个split-area & 使用firstAreaDefaultSize & 使用了lastAreaDefaultSize
            if (splitCount === 1) {
              res = {[dimension]: `calc(${props.firstAreaDefaultSize}px - ${gutterSize}px)`};
            } else if (splitCount === 3) {
              res = {[dimension]: `calc(${props.lastAreaDefaultSize}px - ${gutterSize}px)`};
            } else {
              res = {[dimension]: `calc(100% - ${props.firstAreaDefaultSize + props.lastAreaDefaultSize + gutterSize}px)`};
            }
          } else {
            res = {[dimension]: `calc(${size}% - ${gutterSize}px)`};
          }
          // console.log("@@@@###", res)
          return res
        };
      }
      //@ts-ignore
      data.value.instance = Split(data.value.elements ?? [],
          splitOptions as Split.Options
      )
    };
    onMounted(() => {
      data.value.elements = [];
      data.value.sizes = [];
      data.value.minSizes = [];
      var parentVal = parent.value as unknown as HTMLElement;

      if (parentVal) {
        for (var i = 0; i < parentVal.children.length; i++) {
          var child = parentVal.children[i];
          data.value.elements.push(child);
        }
      }
      if (ctx.slots.default) {
        ctx.slots.default()?.forEach((vnode: VNode) => {
          var vodeType = vnode.type as any;
          if (vodeType.name == "SplitArea") {
            if (vnode.props) {
              var a = vnode.props as {
                size: number;
                minSize: number;
              };
              data.value.sizes?.push(a.size);
              data.value.minSizes?.push(a.minSize);
            }
          }
        });
        splitSumCount = ctx.slots.default().length;
      }
      init();
    });

    const reset = () => {
      useFirstDefaultSize = props.firstAreaDefaultSize && props.firstAreaDefaultSize > 0;
      useLastDefaultSize = props.lastAreaDefaultSize && props.lastAreaDefaultSize > 0;
      init();
    };
    const getSizes = () => {
      return data.value.instance?.getSizes() || 0;
    };

    return {data, init, parent, reset, getSizes};
  },
});
</script>

<style>
.split {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  overflow-y: auto;
  overflow-x: hidden;
  height: 100%;
  width: 100%;
}

.gutter {
  background-color: #eee;
  background-repeat: no-repeat;
  background-position: 50%;
}

.gutter.gutter-horizontal {
  cursor: col-resize;
  background-image: url("");
}

.gutter.gutter-vertical {
  cursor: row-resize;
  background-image: url("");
}

.split.split-horizontal,
.gutter.gutter-horizontal {
  height: 100%;
  float: left;
}
</style>

